package controller;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import ball.Ball;
import barrier.Barrier;
import barrier.Wall;
import controllable_component.Plate;
import util.Contents;
/*
 * 游戏控制器类
 */
public class GameController {

	//球
	private Ball ball;
	//记录所有碰撞物
	private List<Barrier> barriers = new ArrayList<>();
	//挡板
	private Plate plate;
	//游戏中是否有球
	private boolean haveBall;
	//游戏中是否有挡板
	private boolean havePlate;
	// 画布
	private final BufferedImage bufImg = new BufferedImage(Contents.ALL_LATTICE_WIDTH, Contents.ALL_LATTICE_HEIGHT,
			BufferedImage.TYPE_4BYTE_ABGR);
	private Graphics bufG;

	public GameController() {
		bufG = bufImg.getGraphics();
		Wall newWall = new Wall(0, 0);	// 设置边缘
		addBarrier(newWall);	// 添加边缘墙
		ball = null;
		haveBall = false;
		havePlate = false;
	}

	//游戏单位时间进行一步
	public void oneStep() {
		//判定球是否与障碍物发生碰撞
		collisionJudge();
		if (ball != null && !ball.getHaveBall())	// 处理黑洞
			deleteBall();
		if (haveBall)
			ball.move();	// 处理球的移动
	}

	//障碍物碰撞检测
	public void collisionJudge() {
		for (Barrier nowBarrier : barriers) {
			nowBarrier.isCollided(ball);
		}
	}

	//获取球是否存在
	public boolean getHaveBall() {
		return haveBall;
	}

	//添加障碍物
	public boolean addBarrier(Barrier newBarrier) {
		// 挡板不能重复添加
		if (havePlate && newBarrier.getType().equals("Plate"))
			return false;
		// 球不能重复添加
		if (haveBall && newBarrier.getType().equals("Ball"))
			return false;
		// 不能在当前位置添加多个障碍物
		for (Barrier nowBarrier : barriers) {
			if (isBarrierClashed(nowBarrier, newBarrier))
				return false;
		}
		// 特殊实体处理
		// 添加板子
		if (newBarrier.getType().equals("Plate")) {
			plate = (Plate) newBarrier;
			havePlate = true;
		}
		// 添加球
		if (newBarrier.getType().equals("Ball")) {
			ball = (Ball) newBarrier;
			haveBall = true;
		}
		// 添加其他实体
		barriers.add(newBarrier);
		return true;
	}

	// 根据坐标确定实体
	public Barrier chooseBarrier(double x, double y) {
		for (Barrier barrier : barriers) {
			if (barrier.getType().equals("Wall"))
				continue;
			double bX = barrier.getX(), bY = barrier.getY();
			double bEx = barrier.getEx(), bEy = barrier.getEy();
			// 确定实体边缘
			if (x >= bX && x < bEx && y >= bY && y < bEy) {
				return barrier;
			}
		}
		return null;
	}

	//删除障碍物
	public boolean deleteBarrier(double x, double y) {
		Barrier nowBarrier = chooseBarrier(x, y);
		if (nowBarrier == null)
			return false;
		if (nowBarrier.getType().equals("Plate")) {
			plate = null;
			havePlate = false;
		}
		if (nowBarrier.getType().equals("Ball")) {
			ball = null;
			haveBall = false;
		}
		barriers.remove(nowBarrier);
		return true;
	}

	//删除球
	public void deleteBall() {
		if (haveBall == false)
			return;
		haveBall = false;
		ball = null;
		for (Barrier barrier : barriers) {
			if (barrier.getType().equals("Ball")) {
				barriers.remove(barrier);
				break;
			}
		}
	}

	//缩小物体
	public boolean shrinkBarrier(double x, double y) {
		Barrier nowBarrier = chooseBarrier(x, y);
		if (nowBarrier == null)
			return false;
		return nowBarrier.toSmaller();
	}

	//放大物体
	public boolean enlargeBarrier(double x, double y) {
		Barrier nowBarrier = chooseBarrier(x, y);
		if (nowBarrier == null)
			return false;
		if (nowBarrier.toBigger() == false)
			return false;
		for (Barrier barrier : barriers) {
			if (isBarrierEqual(barrier, nowBarrier))
				continue;
			if (isBarrierClashed(barrier, nowBarrier)) {
				nowBarrier.toSmaller();
				return false;
			}
		}
		return true;
	}

	//旋转物体
	public boolean rotateBarrier(double x, double y) {
		Barrier nowBarrier = chooseBarrier(x, y);
		if (nowBarrier == null)
			return false;
		if (nowBarrier.rotate() == false)
			return false;
		if (nowBarrier.getType() == "Plate") {
			for (Barrier barrier : barriers) {
				if (isBarrierEqual(barrier, nowBarrier))
					continue;
				if (isBarrierClashed(barrier, nowBarrier)) {
					nowBarrier.rotate();
					return false;
				}
			}
		}
		return true;
	}

	//判定一个晶格中是否存在多个物体
	public boolean isBarrierClashed(Barrier b1, Barrier b2) {
		if (b1.getType() == "Wall" || b2.getType() == "Wall")
			return false;
		double b1X = b1.getX(), b1Y = b1.getY();
		double b1Ex = b1.getEx(), b1Ey = b1.getEy();
		double b2X = b2.getX(), b2Y = b2.getY();
		double b2Ex = b2.getEx(), b2Ey = b2.getEy();
		if (b1X >= b2X && b1X < b2Ex && b1Y >= b2Y && b1Y < b2Ey)
			return true;
		if (b1X >= b2X && b1X < b2Ex && b1Ey > b2Y && b1Ey <= b2Ey)
			return true;
		if (b1Ex > b2X && b1Ex <= b2Ex && b1Ey > b2Y && b1Ey <= b2Ey)
			return true;
		if (b1Ex > b2X && b1Ex <= b2Ex && b1Y >= b2Y && b1Y < b2Ey)
			return true;
		return false;
	}

	public boolean isBarrierEqual(Barrier b1, Barrier b2) {
		return b1.getX() == b2.getX() && b1.getY() == b2.getY();
	}

	//绘制图像
	public void paint() {
		for (Barrier barrier : barriers) {
			if (!haveBall && barrier.getType().equals("Ball"))
				continue;
			barrier.paint(bufG);
		}
	}

	//根据键盘移动挡板
	public void movePlate(int keyNum) {
		switch (keyNum) {
		case 37:
			plate.moveLeft();
			break;
		case 38:
			plate.moveUp();
			break;
		case 39:
			plate.moveRight();
			break;
		case 40:
			plate.moveDown();
			break;
		default:
			break;

		}
	}

	//获取图片
	public BufferedImage getImage() {
		paint();
		return bufImg;
	}

	//添加游戏信息
	public void addGameData(Barrier newBarrier,int angle) {
		if (newBarrier.getType().equals("Wall"))	// 墙仅在创建时添加 现在添加为非法操作
			return;
		// 特殊情况处理
		if (newBarrier.getType().equals("Plate")) {
			plate = (Plate) newBarrier;
			havePlate = true;
		}
		if (newBarrier.getType().equals("Ball")) {
			ball = (Ball) newBarrier;
			haveBall = true;
		}
		barriers.add(newBarrier);
		while(angle != 0) {
			angle--;
			newBarrier.rotate();
		}
		return;
	}

	// 获取游戏当前障碍物
	public List<Barrier> getGameData() {
		return barriers;
	}
}
